#ifndef __WIZ_BNF_ACTOR_CONVERT_HPP__SHANHAOBO_19800429__
#define __WIZ_BNF_ACTOR_CONVERT_HPP__SHANHAOBO_19800429__

#include "../../Base/WizBase.hpp"
#include "../../DataType/Tuple/WizDataTypeTuple.hpp"

#include "./WizBNFActorComposite.hpp"

namespace Wiz
{
    namespace BNF
    {
        namespace Actor
        {
            ///////////////////////////////////

            template <::Wiz::Int::Type N, typename TupleResultT, typename ActorTupleT>
            struct ConvertActor
            {
                typedef typename ::Wiz::Tuple::Element::Type<N, TupleResultT>::tType tElementType;

                template <::Wiz::Bool::Type C>
                struct IsDefault_t
                {};
                typedef IsDefault_t<::Wiz::Bool::True>          IsDefault;
                typedef IsDefault_t<::Wiz::Bool::False>         IsNotDefault;

                static tElementType ActorElement(ActorTupleT const&, IsDefault)
                {
                    return tElementType();
                }

                static tElementType ActorElement(ActorTupleT const& ActorTuple, IsNotDefault)
                {
                    WIZ_STATIC_ASSERT(ActorTupleT::v_Length <= TupleResultT::v_Length);
                    return ActorTuple[::Wiz::Tuple::Index::Type<N>()]();
                }

                static tElementType Do(ActorTupleT const& ActorTuple)
                {
                    return ActorElement(ActorTuple, IsDefault_t<(N >= ActorTupleT::v_Length)>());
                }
            };

            ///////////////////////////////////
            namespace Inner
            {
                template <::Wiz::Int::Type N>
                struct ConvertActor
                {};

                ///////////////////////////////////////
                template <>
                struct ConvertActor<1>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;

                            return TupleResultT(tConverter0::Do(ActorTuple));
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<2>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple)
                                );
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<3>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;
                            typedef ::Wiz::BNF::Actor::ConvertActor<2, TupleResultT, ActorTupleT> tConverter2;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple),
                                tConverter2::Do(ActorTuple)
                                );
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<4>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;
                            typedef ::Wiz::BNF::Actor::ConvertActor<2, TupleResultT, ActorTupleT> tConverter2;
                            typedef ::Wiz::BNF::Actor::ConvertActor<3, TupleResultT, ActorTupleT> tConverter3;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple),
                                tConverter2::Do(ActorTuple),
                                tConverter3::Do(ActorTuple)
                                );
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<5>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;
                            typedef ::Wiz::BNF::Actor::ConvertActor<2, TupleResultT, ActorTupleT> tConverter2;
                            typedef ::Wiz::BNF::Actor::ConvertActor<3, TupleResultT, ActorTupleT> tConverter3;
                            typedef ::Wiz::BNF::Actor::ConvertActor<4, TupleResultT, ActorTupleT> tConverter4;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple),
                                tConverter2::Do(ActorTuple),
                                tConverter3::Do(ActorTuple),
                                tConverter4::Do(ActorTuple)
                                );
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<6>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;
                            typedef ::Wiz::BNF::Actor::ConvertActor<2, TupleResultT, ActorTupleT> tConverter2;
                            typedef ::Wiz::BNF::Actor::ConvertActor<3, TupleResultT, ActorTupleT> tConverter3;
                            typedef ::Wiz::BNF::Actor::ConvertActor<4, TupleResultT, ActorTupleT> tConverter4;
                            typedef ::Wiz::BNF::Actor::ConvertActor<5, TupleResultT, ActorTupleT> tConverter5;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple),
                                tConverter2::Do(ActorTuple),
                                tConverter3::Do(ActorTuple),
                                tConverter4::Do(ActorTuple),
                                tConverter5::Do(ActorTuple)
                                );
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<7>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;
                            typedef ::Wiz::BNF::Actor::ConvertActor<2, TupleResultT, ActorTupleT> tConverter2;
                            typedef ::Wiz::BNF::Actor::ConvertActor<3, TupleResultT, ActorTupleT> tConverter3;
                            typedef ::Wiz::BNF::Actor::ConvertActor<4, TupleResultT, ActorTupleT> tConverter4;
                            typedef ::Wiz::BNF::Actor::ConvertActor<5, TupleResultT, ActorTupleT> tConverter5;
                            typedef ::Wiz::BNF::Actor::ConvertActor<6, TupleResultT, ActorTupleT> tConverter6;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple),
                                tConverter2::Do(ActorTuple),
                                tConverter3::Do(ActorTuple),
                                tConverter4::Do(ActorTuple),
                                tConverter5::Do(ActorTuple),
                                tConverter6::Do(ActorTuple)
                                );
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<8>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;
                            typedef ::Wiz::BNF::Actor::ConvertActor<2, TupleResultT, ActorTupleT> tConverter2;
                            typedef ::Wiz::BNF::Actor::ConvertActor<3, TupleResultT, ActorTupleT> tConverter3;
                            typedef ::Wiz::BNF::Actor::ConvertActor<4, TupleResultT, ActorTupleT> tConverter4;
                            typedef ::Wiz::BNF::Actor::ConvertActor<5, TupleResultT, ActorTupleT> tConverter5;
                            typedef ::Wiz::BNF::Actor::ConvertActor<6, TupleResultT, ActorTupleT> tConverter6;
                            typedef ::Wiz::BNF::Actor::ConvertActor<7, TupleResultT, ActorTupleT> tConverter7;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple),
                                tConverter2::Do(ActorTuple),
                                tConverter3::Do(ActorTuple),
                                tConverter4::Do(ActorTuple),
                                tConverter5::Do(ActorTuple),
                                tConverter6::Do(ActorTuple),
                                tConverter7::Do(ActorTuple)
                                );
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<9>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;
                            typedef ::Wiz::BNF::Actor::ConvertActor<2, TupleResultT, ActorTupleT> tConverter2;
                            typedef ::Wiz::BNF::Actor::ConvertActor<3, TupleResultT, ActorTupleT> tConverter3;
                            typedef ::Wiz::BNF::Actor::ConvertActor<4, TupleResultT, ActorTupleT> tConverter4;
                            typedef ::Wiz::BNF::Actor::ConvertActor<5, TupleResultT, ActorTupleT> tConverter5;
                            typedef ::Wiz::BNF::Actor::ConvertActor<6, TupleResultT, ActorTupleT> tConverter6;
                            typedef ::Wiz::BNF::Actor::ConvertActor<7, TupleResultT, ActorTupleT> tConverter7;
                            typedef ::Wiz::BNF::Actor::ConvertActor<8, TupleResultT, ActorTupleT> tConverter8;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple),
                                tConverter2::Do(ActorTuple),
                                tConverter3::Do(ActorTuple),
                                tConverter4::Do(ActorTuple),
                                tConverter5::Do(ActorTuple),
                                tConverter6::Do(ActorTuple),
                                tConverter7::Do(ActorTuple),
                                tConverter8::Do(ActorTuple)
                                );
                        }
                    };
                };
                ///////////////////////////////////////
                template <>
                struct ConvertActor<10>
                {
                    template <typename TupleResultT, typename ActorTupleT>
                    struct Apply
                    {
                        static TupleResultT Do(ActorTupleT const& ActorTuple)
                        {
                            typedef ::Wiz::BNF::Actor::ConvertActor<0, TupleResultT, ActorTupleT> tConverter0;
                            typedef ::Wiz::BNF::Actor::ConvertActor<1, TupleResultT, ActorTupleT> tConverter1;
                            typedef ::Wiz::BNF::Actor::ConvertActor<2, TupleResultT, ActorTupleT> tConverter2;
                            typedef ::Wiz::BNF::Actor::ConvertActor<3, TupleResultT, ActorTupleT> tConverter3;
                            typedef ::Wiz::BNF::Actor::ConvertActor<4, TupleResultT, ActorTupleT> tConverter4;
                            typedef ::Wiz::BNF::Actor::ConvertActor<5, TupleResultT, ActorTupleT> tConverter5;
                            typedef ::Wiz::BNF::Actor::ConvertActor<6, TupleResultT, ActorTupleT> tConverter6;
                            typedef ::Wiz::BNF::Actor::ConvertActor<7, TupleResultT, ActorTupleT> tConverter7;
                            typedef ::Wiz::BNF::Actor::ConvertActor<8, TupleResultT, ActorTupleT> tConverter8;
                            typedef ::Wiz::BNF::Actor::ConvertActor<9, TupleResultT, ActorTupleT> tConverter9;

                            return TupleResultT
                                (
                                tConverter0::Do(ActorTuple),
                                tConverter1::Do(ActorTuple),
                                tConverter2::Do(ActorTuple),
                                tConverter3::Do(ActorTuple),
                                tConverter4::Do(ActorTuple),
                                tConverter5::Do(ActorTuple),
                                tConverter6::Do(ActorTuple),
                                tConverter7::Do(ActorTuple),
                                tConverter8::Do(ActorTuple),
                                tConverter9::Do(ActorTuple)
                                );
                        }
                    };
                };
            } /// end of namespace Inner

            template <typename TupleResultT, typename ActorTupleT>
            TupleResultT ConvertActors(ActorTupleT const& ActorTuple)
            {
                WIZ_STATIC_ASSERT(ActorTupleT::v_Length <= TupleResultT::v_Length);
                return ::Wiz::BNF::Actor::Inner::ConvertActor<TupleResultT::v_Length> ::template Apply<TupleResultT, ActorTupleT>::Do(ActorTuple);
            }
            ///////////////////////////////////
        } /// end of namespace Actor
    } /// end of namespace BNF
} /// end of namespace Wiz

#endif /*__WIZ_BNF_ACTOR_CONVERT_HPP__SHANHAOBO_19800429__*/
